/**
 * Build and upload assets for macOS(aarch)
 */
import fs from 'fs-extra'
import path from 'path'
import { exit } from 'process'
import { createRequire } from 'module'
import { getOctokit, context } from '@actions/github'

const require = createRequire(import.meta.url)

async function resolve() {
  if (!process.env.GITHUB_TOKEN) {
    throw new Error('GITHUB_TOKEN is required')
  }
  if (!process.env.GITHUB_REPOSITORY) {
    throw new Error('GITHUB_REPOSITORY is required')
  }
  if (!process.env.TAURI_PRIVATE_KEY) {
    throw new Error('TAURI_PRIVATE_KEY is required')
  }
  if (!process.env.TAURI_KEY_PASSWORD) {
    throw new Error('TAURI_KEY_PASSWORD is required')
  }

  const { version } = require('../package.json')

  const cwd = process.cwd()
  const bundlePath = path.join(cwd, 'src-tauri/target/release/bundle')
  const join = (p) => path.join(bundlePath, p)

  const appPathList = [
    join('macos/Qucent Amc.aarch64.app.tar.gz'),
    join('macos/Qucent Amc.aarch64.app.tar.gz.sig'),
  ]

  for (const appPath of appPathList) {
    if (fs.pathExistsSync(appPath)) {
      fs.removeSync(appPath)
    }
  }

  fs.copyFileSync(join('macos/Qucent Amc.app.tar.gz'), appPathList[0])
  fs.copyFileSync(join('macos/Qucent Amc.app.tar.gz.sig'), appPathList[1])

  const options = { owner: context.repo.owner, repo: context.repo.repo }
  const github = getOctokit(process.env.GITHUB_TOKEN)

  const { data: release } = await github.rest.repos.getReleaseByTag({
    ...options,
    tag: `v${version}`,
  })

  if (!release.id) throw new Error('failed to find the release')

  await uploadAssets(release.id, [
    join(`dmg/Qucent Amc_${version}_aarch64.dmg`),
    ...appPathList,
  ])
}

// From tauri-apps/tauri-action
// https://github.com/tauri-apps/tauri-action/blob/dev/packages/action/src/upload-release-assets.ts
async function uploadAssets(releaseId, assets) {
  const github = getOctokit(process.env.GITHUB_TOKEN)

  // Determine content-length for header to upload asset
  const contentLength = (filePath) => fs.statSync(filePath).size

  for (const assetPath of assets) {
    const headers = {
      'content-type': 'application/zip',
      'content-length': contentLength(assetPath),
    }

    const ext = path.extname(assetPath)
    const filename = path.basename(assetPath).replace(ext, '')
    const assetName = path.dirname(assetPath).includes(`target${path.sep}debug`)
      ? `${filename}-debug${ext}`
      : `${filename}${ext}`

    console.log(`[INFO]: Uploading ${assetName}...`)

    try {
      await github.rest.repos.uploadReleaseAsset({
        headers,
        name: assetName,
        data: fs.readFileSync(assetPath),
        owner: context.repo.owner,
        repo: context.repo.repo,
        release_id: releaseId,
      })
    } catch (error) {
      console.log(error.message)
    }
  }
}

if (process.platform === 'darwin' && process.arch === 'arm64') {
  resolve()
} else {
  console.error('invalid')
  exit(1)
}
